package com.anlogic.sdk.efuse.utils;

import java.io.File;

import org.eclipse.core.runtime.IProgressMonitor;

import com.anlogic.sdk.tools.exetool.ExeTool;
import com.anlogic.sdk.utils.ECCUtils;
import com.anlogic.sdk.utils.EnvUtils;
import com.anlogic.sdk.utils.FileUtils;

public class ProgramEfuseUtils {
	private static final String SCRIPT_FILE_NAME = EnvUtils.getIDEToolPath() + "/data/program_efuse.tcl";
	private static final String PROGRAM_EFUSE = "program_efuse";

	private static ExeTool anlogicTool = new ExeTool("Download Tool");

	public static String getEncKeyCmd(String encKeyHashValue) {
		int[] encKeyEcc = ECCUtils.getEcc(encKeyHashValue);

		String programEncKeyCmd = String.format(
				"ps_efuse_operate -w -l {enc_key0:%s} -svf \"$::env(IDE_ROOT_PATH)/tools/data/efuse7_enckey_wr.svf\" -comment -iopll 33",
				encKeyHashValue);
		String programEncKeyEccCmd = String.format(
				"ps_efuse_operate -w -l {enc_key0__b063_0_ecc:%X enc_key0__b127_64_ecc:%X enc_key0__b191_128_ecc:%X enc_key0__b255_192_ecc:%X} -svf \"$::env(IDE_ROOT_PATH)/tools/data/efuse7_enckeyecc_wr.svf\" -comment -iopll 33",
				encKeyEcc[0], encKeyEcc[1], encKeyEcc[2], encKeyEcc[3]);

		String cmd = programEncKeyCmd + "\n" + programEncKeyEccCmd;
		return cmd;
	}

	public static String getEncKeyCmd(String encKeyHashValue, String encKey2HashValue) {
		int[] encKeyEcc = ECCUtils.getEcc(encKeyHashValue);
		int[] encKey2Ecc = ECCUtils.getEcc(encKey2HashValue);

		String encKeyCmd = String.format(
				"ps_efuse_operate -w -l {enc_key0:%s enc_key1:%s} -svf \"$::env(IDE_ROOT_PATH)/tools/data/efuse7_enckey_wr.svf\" -comment -iopll 33",
				encKeyHashValue, encKey2HashValue);
		String encKeyEccCmd = String.format(
				"ps_efuse_operate -w -l {enc_key0__b063_0_ecc:%X enc_key0__b127_64_ecc:%X enc_key0__b191_128_ecc:%X enc_key0__b255_192_ecc:%X "
						+ "enc_key1__b063_0_ecc:%X enc_key1__b127_64_ecc:%X enc_key1__b191_128_ecc:%X enc_key1__b255_192_ecc:%X} -svf \"$::env(IDE_ROOT_PATH)/tools/data/efuse7_enckeyecc_wr.svf\" -comment -iopll 33",
				encKeyEcc[0], encKeyEcc[1], encKeyEcc[2], encKeyEcc[3], encKey2Ecc[0], encKey2Ecc[1], encKey2Ecc[2],
				encKey2Ecc[3]);

		String cmd = encKeyCmd + "\n" + encKeyEccCmd;
		return cmd;
	}

	public static String getPubKeyCmd(String pubKeyHashValue) {
		int[] pubKeyEcc = ECCUtils.getEcc(pubKeyHashValue);

		String pubKeyCmd = String.format(
				"ps_efuse_operate -w -l {ppk0_hash:%s} -svf \"$::env(IDE_ROOT_PATH)/tools/data/efuse7_ppkhash_wr.svf\" -comment -iopll 33",
				pubKeyHashValue);
		String pubKeyEccCmd = String.format(
				"ps_efuse_operate -w -l {ppk0_hash__b063_0_ecc:%X ppk0_hash__b127_64_ecc:%X ppk0_hash__b191_128_ecc:%X ppk0_hash__b255_192_ecc:%X} -svf \"$::env(IDE_ROOT_PATH)/tools/data/efuse7_ppkhashecc_wr.svf\" -comment -iopll 33",
				pubKeyEcc[0], pubKeyEcc[1], pubKeyEcc[2], pubKeyEcc[3]);

		String cmd = pubKeyCmd + "\n" + pubKeyEccCmd;
		return cmd;
	}

	public static String getPubKeyCmd(String pubKeyHashValue, String pubKey2HashValue) {
		int[] pubKeyEcc = ECCUtils.getEcc(pubKeyHashValue);
		int[] pubKey2Ecc = ECCUtils.getEcc(pubKey2HashValue);

		String pubKeyCmd = String.format(
				"ps_efuse_operate -w -l {ppk0_hash:%s ppk1_hash:%s} -svf \"$::env(IDE_ROOT_PATH)/tools/data/efuse7_ppkhash_wr.svf\" -comment -iopll 33",
				pubKeyHashValue, pubKey2HashValue);
		String pubKeyEccCmd = String.format(
				"ps_efuse_operate -w -l {ppk0_hash__b063_0_ecc:%X ppk0_hash__b127_64_ecc:%X ppk0_hash__b191_128_ecc:%X ppk0_hash__b255_192_ecc:%X "
						+ "ppk1_hash__b063_0_ecc:%X ppk1_hash__b127_64_ecc:%X ppk1_hash__b191_128_ecc:%X ppk1_hash__b255_192_ecc:%X} -svf \"$::env(IDE_ROOT_PATH)/tools/data/efuse7_ppkhashecc_wr.svf\" -comment -iopll 33",
				pubKeyEcc[0], pubKeyEcc[1], pubKeyEcc[2], pubKeyEcc[3], pubKey2Ecc[0], pubKey2Ecc[1], pubKey2Ecc[2],
				pubKey2Ecc[3]);

		String cmd = pubKeyCmd + "\n" + pubKeyEccCmd;
		return cmd;
	}

	public static String getEncTypeCmd(int encType) {
		String encKeyEncTypeCmd = String.format(
				"ps_efuse_operate -w -l {enc_type_sel:%X} -svf \"$::env(IDE_ROOT_PATH)/tools/data/efuse7_enc_type_sel.svf\" -comment -iopll 33",
				encType);
		return encKeyEncTypeCmd;
	}
	
	public static String getAuthTypeCmd(int authType) {
		String authTypeCmd = String.format(
				"ps_efuse_operate -w -l {auth_type_sel:%X} -svf \"$::env(IDE_ROOT_PATH)/tools/data/efuse7_auth_type_sel.svf\" -comment -iopll 33",
				authType);
		return authTypeCmd;
	}
	
	public static String getEncKeyWriteLockCmd(boolean encKeyWriteLock) {
		int encKeyWriteLockValue = encKeyWriteLock ? 1 : 0;
		String encKeyWriteLockCmd = String.format(
				"ps_efuse_operate -w -l {enc_key0__wr_lk:%X} -svf \"$::env(IDE_ROOT_PATH)/tools/data/efuse7_enckey_wr_lk.svf\" -comment -iopll 33",
				encKeyWriteLockValue);
		return encKeyWriteLockCmd;
	}

	public static String getEncKeyWriteLockCmd(boolean encKeyWriteLock, boolean encKey2WriteLock) {
		int encKeyWriteLockValue = encKeyWriteLock ? 1 : 0;
		int encKey2WriteLockValue = encKey2WriteLock ? 1 : 0;
		String encKeyWriteLockCmd = String.format(
				"ps_efuse_operate -w -l {enc_key0__wr_lk:%X enc_key1__wr_lk:%X} -svf \"$::env(IDE_ROOT_PATH)/tools/data/efuse7_enckey_wr_lk.svf\" -comment -iopll 33",
				encKeyWriteLockValue, encKey2WriteLockValue);
		return encKeyWriteLockCmd;
	}

	public static String getPubKeyWriteLockCmd(boolean ppkWriteLock) {
		int ppkWriteLockValue = ppkWriteLock ? 1 : 0;
		String pubKeyWriteLockCmd = String.format(
				"ps_efuse_operate -w -l {ppk0_hash__wr_lk:%X} -svf \"$::env(IDE_ROOT_PATH)/tools/data/efuse7_ppkhash_wr_lk.svf\" -comment -iopll 33",
				ppkWriteLockValue);
		return pubKeyWriteLockCmd;
	}

	public static String getPubKeyWriteLockCmd(boolean ppkWriteLock, boolean ppk2WriteLock) {
		int ppkWriteLockValue = ppkWriteLock ? 1 : 0;
		int ppk2WriteLockValue = ppk2WriteLock ? 1 : 0;
		String pubKeyWriteLockCmd = String.format(
				"ps_efuse_operate -w -l {ppk0_hash__wr_lk:%X ppk1_hash__wr_lk:%X} -svf \"$::env(IDE_ROOT_PATH)/tools/data/efuse7_ppkhash_wr_lk.svf\" -comment -iopll 33",
				ppkWriteLockValue, ppk2WriteLockValue);
		return pubKeyWriteLockCmd;
	}

	public static String getEncKeyRevokeCmd(boolean revokeEncKey) {
		int revokeEncKeyValue = revokeEncKey ? 1 : 0;
		String revokeEncKeyCmd = String.format(
				"ps_efuse_operate -w -l {enc_key0_invld:%X} -svf \"$::env(IDE_ROOT_PATH)/tools/data/efuse7_enckey_revoke.svf\" -comment -iopll 33",
				revokeEncKeyValue);
		return revokeEncKeyCmd;
	}

	public static String getPubKeyRevokeCmd(boolean revokePpk) {
		int revokePpkValue = revokePpk ? 1 : 0;
		String revokePubKeyCmd = String.format(
				"ps_efuse_operate -w -l {ppk0_invld:%X} -svf \"$::env(IDE_ROOT_PATH)/tools/data/efuse7_ppkhash_revoke.svf\" -comment -iopll 33",
				revokePpkValue);
		return revokePubKeyCmd;
	}
	
	public static String getTRNGWriteCmd(boolean trngWrite) {
		int trngWriteValue = trngWrite ? 1 : 0;
		String cmd = String.format(
				"ps_efuse_operate -w -l {sw_ext:%X} -svf \"$::env(IDE_ROOT_PATH)/tools/data/efuse7_trng_wr.svf\" -comment -iopll 33",
				trngWriteValue);
		return cmd;
	}

	public static void writeScript(String content) {
		FileUtils.write(new File(SCRIPT_FILE_NAME), content);
	}

	public static String getCmd() {
		return PROGRAM_EFUSE;
	}

	public static void programEfuse() {
		anlogicTool.executeJob(getCmd());
	}

	public static void programEfuse(IProgressMonitor monitor) {
		anlogicTool.launch(monitor, getCmd());
	}
}
